package com.MySpring6.reflection;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static java.lang.reflect.AccessibleObject.setAccessible;

public class TestCar {

    //1 获取class对象多种方式
    @Test
    public void test() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //1 类名.class
        Class clazz = Car.class;
        //2 类名.getClass()
        Class clazz2 = new Car().getClass();
        //3 Class.forName("全类名")
        Class clazz3 = Class.forName("com.MySpring6.reflection.Car");

        //实例化
        Car car = (Car) clazz3.getDeclaredConstructor().newInstance();
        System.out.println(car);
    }
    //2 获取构造方法
    @Test
    public void test02()
    {
        Class clazz = Car.class;
        //获取所有构造方法
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for(Constructor c : constructors)
        {
            System.out.println(c.getName());
        }
    }
    //3 获取属性
    @Test
    public void test03() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class clazz = Car.class;
        Car car = (Car)clazz.getDeclaredConstructor().newInstance();
        Field[] fields = clazz.getDeclaredFields();
        for(Field f : fields)
        {
            if(f.getName().equals("model"))
            {
                f.setAccessible(true);
                f.set(car, "宝马");
            }
            System.out.println(f.getName());
            System.out.println(car);
        }
    }
    //4 获取方法
    @Test
    public void test04() throws Exception{
        Car car = new Car("奔驰",1,"黑色");
        Class clazz = car.getClass();
        //Class clazz = new Car("奔驰",1,"黑色").getClass();

        //public方法
        Method[] methods = clazz.getMethods();
        for(Method m : methods)
        {
            //System.out.println(m.getName());
            //执行方法
            if(m.getName().equals("toString"))
            {
                String invoke = (String)m.invoke(car);
                System.out.println(invoke);
            }
        }
        //私有方法
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods)
        {
            if(m.getName().equals("drive"))
            {
                m.setAccessible(true);
                m.invoke(car);
            }
        }

    }

}
